
#ifndef GUIWP_WIDGET_BASE__
#define GUIWP_WIDGET_BASE__

#include <list>
#include <iostream>
#include <algorithm>

#include "moteur_base.hpp"

struct deleter
{
    template <typename T>
    void operator() (T*& t)
    {
	delete t;
	t=NULL;
    }
};

namespace GUIWP
{
class widget_base
{
protected:

    static std::list<widget_base*> allDyn;

    std::list<widget_base*> children;
    widget_base* parent;
  
    widget_base(const widget_base&){}
    widget_base& operator=(const widget_base& other);
    widget_base(){}
public:

    virtual void draw(Moteur_Base& ) =0;

    void register_child(widget_base* w)
    {
	children.push_back(w);
    }

    void remove_child(widget_base* w)
    {
	std::list<widget_base*>::iterator it= std::find(children.begin(),children.end(),w);
	if(it != children.end())
	    children.erase(it);
    }

    widget_base(widget_base* parent_) : parent(parent_)
    {
	if(parent_ != NULL)
	{
	    parent_->register_child(this);
	}
    }
  
    virtual ~widget_base()
    {
	destroy();
    }
  
    virtual void destroy()
    {
	std::for_each(children.begin(), children.end(), deleter());
	
    }

    void* operator new(std::size_t t)
    {
	std::cout<<"widget_base new"<<std::endl;
	void *storage = malloc(t);
	if(NULL == storage) {
	    throw "allocation fail : no free memory";
	}

	allDyn.push_back(static_cast<widget_base*>(storage));
	return storage;
    }

    void operator delete(void* p)
    {
	std::cout<<"A delete"<<std::endl;
	widget_base* pc = static_cast<widget_base*>(p); 

	if(std::find(allDyn.begin(),allDyn.end(),pc) != allDyn.end())
	    std::cout<<pc<<" Alloue dynamiquement"<<std::endl;

	free(pc);

	std::cout<<std::endl;
    }

};
}
#endif // GUIWP_WIDGET_BASE__
